#include "head.h"

// 清空缓冲区
/* void clear_input_buffer() { */
/*     int c; */
/*     while ((c = getchar()) != '\n' && c != EOF) { */
/*         // 丢弃缓冲区中的字符 */
/*     } */   
/* } */


// 功能：上传文件
int putsFile(char *clientPath, char *serverPath, int sockfd){
    int fd = open(clientPath, O_RDWR);

    int fileSize = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);

    // 传送指令，以及路径
    TLVRequest(sockfd, serverPath, PUTS);

    // 接收来自服务段的响应
    train_t train;
    bzero(&train, sizeof(train));
    // 服务段响应客户端要上传的文件在服务有多大
    recv(sockfd, &train.type, sizeof(train.type), MSG_WAITALL);
    recv(sockfd, &train.args, sizeof(int), MSG_WAITALL);
    recv(sockfd, &train.len, sizeof(train.len), MSG_WAITALL);
    /* recv(sockfd, train.buf, train.length, MSG_WAITALL); */

    /* off_t serverCurSize = atoi(train.buf); */
    if(fileSize < train.len){
        // 返回拒绝请求，本次上传取消
        TLVRequest(sockfd, NULL, CANCEL);
        printf("本地文件与服务器文件不一致\n");
        return 1;
    }
    // 返回确认请求,准备传输文件的大小
    TLVRequestLen(sockfd, fileSize - train.len);
    
    off_t temp = train.len;
    ftruncate(fd, fileSize);
    sendfile(sockfd, fd, &temp, fileSize - train.len);

    printf("传输成功\n");
    close(fd);
    return 0;
}

// 功能：下载文件
int getsFile(char *serverPath, char *clientPath, int sockfd){

    char flag = 'n';

    // 下载的位置不存在，新建一个
    if(access(clientPath, F_OK) != 0){ 
        char dir[1024] = {0};
        int index = 0;
        for(size_t i = 0; i < strlen(clientPath); i++){
            if(clientPath[i] == '/')index = i;
        }
        if(index != 0){
            // 创目录
            memcpy(dir, clientPath, index + 1);
            mkdir(dir, 0766);
        }
    }

    // 打开文件，并获取文件大小
    int fd = open(clientPath, O_RDWR | O_CREAT , 0666);

    off_t fileSize = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);
    

    if(fileSize != 0){

        // 文件存在，触发断点重传
        printf("是否断点重传[y/n]\n");
        scanf(" %c", &flag);

        if(flag != 'y'){
            // 不断点重传
            fileSize = 0;
        }
    }
        
    printf("cur fileSize :%lu\n", fileSize);
    
    // 传输指令
    TLVRequest(sockfd, serverPath, GETS);
    // 传输当前客户端已有下载的文件多少字节
    TLVRequestLen(sockfd, fileSize); 
                     
    // 接收服务端将要传送的数据大小
    train_t train;
    bzero(&train, sizeof(train));

    recv(sockfd, &train.type, sizeof(int), MSG_WAITALL);
    recv(sockfd, &train.len, sizeof(int), MSG_WAITALL);
    
    printf("recv size : %d\n", train.len);

    ftruncate(fd, fileSize + train.len);
    
    // 客户端获取文件
    char *buf = (char *)mmap(NULL, fileSize + train.len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    recv(sockfd, buf + fileSize, train.len, MSG_WAITALL);
    
    munmap(buf, fileSize + train.len);
    close(fd);
    return 0;
}
